package com.group.voting_system.controller;

import com.group.voting_system.entity.Candidate;
import com.group.voting_system.entity.User;
import com.group.voting_system.service.ICandidateService;
import com.group.voting_system.service.IUserService;
import com.group.voting_system.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.imageio.ImageIO;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;

/**
 * @Author: xyf
 * @Date: 2019/4/18 21:46
 */
@Controller
public class MediaController {

    @Value("${localPic.path}")
    String picPath;

    @Value("${localVideo.path}")
    String videoPath;

    @Value("${localQR.path}")
    String QRPath;

    @Value("${localExcel.path}")
    String excelPath;

    @Value("${localWord.htmlPath}")
    String htmlPath;

    @Value("${localWord.picPath}")
    String wordPicPath;

    @Value("${localVideo.m3u8}")
    String m3u8Path;

    @Autowired
    IUserService userService;

    @Autowired
    ICandidateService candidateService;

    @GetMapping("/detail/{url}")
    public void detail(HttpServletResponse response,
                       @PathVariable("url") String url) {
        String fileName = htmlPath + url + "/detail.html";
        File file = new File(fileName);
        if (file.exists()) {
            FileInputStream in = null;
            BufferedInputStream bin = null;
            OutputStream out = null;
            byte[] buffer = new byte[1024];
            try {
                in = new FileInputStream(file);
                bin = new BufferedInputStream(in);
                out = response.getOutputStream();
                int i = bin.read(buffer);
                while (i != -1) {
                    out.write(buffer, 0, i);
                    i = bin.read(buffer);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (bin != null) {
                    try {
                        bin.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
    }

    //获取图片
    @GetMapping("/pic/{url}")
    public void pic(HttpServletResponse response,
                    @PathVariable String url) {

        String fileName = picPath + url + "/pic.jpg";
        File file = new File(fileName);
        if (file.exists()) {
            response.setContentType("application/force-download");
            response.addHeader("Content-Disposition",
                    "attachment;fileName=" + url + ".jpg");
            byte[] buffer = new byte[1024];
            FileInputStream in = null;
            BufferedInputStream bin = null;
            OutputStream out = null;
            try {
                in = new FileInputStream(file);
                bin = new BufferedInputStream(in);
                out = response.getOutputStream();
                int i = bin.read(buffer);
                while (i != -1) {
                    out.write(buffer, 0, i);
                    i = bin.read(buffer);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (bin != null) {
                    try {
                        bin.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

//    //获取视频
//    @GetMapping("/video")
//    public void video(HttpServletRequest request,
//                      HttpServletResponse response,
//                      @RequestParam("videoUrl") String videoUrl){
//        String fileName = videoPath + videoUrl + "/video.mp4";
//        String range = request.getHeader("Range");
//        File file = new File(fileName);
//        if (file.exists()){
//
//            ServletContext context = request.getServletContext();
//            //获取mime类型
//            String mimeType = context.getMimeType(fileName);
//            if (mimeType == null) {
//                mimeType = "application/octet-stream";
//            }
//
//            response.setContentType(mimeType);
//
//            String headerKey = "Content-Disposition";
//            String headerVal = String.format("attachment; filename=%s", file.getName());
//            response.setHeader(headerKey, headerVal);
//            //解析断点续传相关信息
//            response.setHeader("Accept-Ranges", "bytes");
//            long downloadSize = file.length();
//            long fromPos = 0, toPos = 0;
//            if (range == null){
//                response.setHeader("Content-Length", downloadSize + "");
//            } else {
//                // 客户端传来range，设置状态为206
//                response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
//                String bytes = range.replaceAll("bytes=", "");
//                String[] arg = bytes.split("-");
//                fromPos = Long.parseLong(arg[0]);
//                if (arg.length == 2) {
//                    toPos = Long.parseLong(arg[1]);
//                }
//                int size;
//                if (toPos > fromPos) {
//                    size = (int) (toPos - fromPos);
//                } else {
//                    size = (int) (downloadSize - fromPos);
//                }
//                response.setHeader("Content-Length", size + "");
//                String cr = String.format("bytes %s-%d/%d", arg[0], file.length()-1, file.length());
//                response.setHeader("Content-Range", cr);
//                downloadSize = size;
//            }
//
//            RandomAccessFile in = null;
//            OutputStream out = null;
//
//            try {
//                in = new RandomAccessFile(file, "r");
//                //设置下载起始位置
//                if (fromPos > 0) {
//                    in.seek(fromPos);
//                }
//
//                //设置缓冲区大小
//                int buff = downloadSize > 4096 ? 4096 : (int) downloadSize;
//                byte[] buffer = new byte[buff];
//                int num;
//                int count = 0;
//                out = response.getOutputStream();
//                while ((num = in.read(buffer)) != -1) {
//                    out.write(buffer, 0, num);
//                    count += num;
//                    //处理最后一段，计算不满缓冲区的大小
//                    if (downloadSize - count < buff) {
//                        buff = (int) (downloadSize - count);
//                        if (buff == 0){
//                            break;
//                        }
//                        buffer = new byte[buff];
//                    }
//                }
//
//                response.flushBuffer();
//            } catch (FileNotFoundException e) {
//                e.printStackTrace();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//    }

    //获取二维码
    @GetMapping("/qr/{id}")
    public void qrCode(@PathVariable("id") Integer id,
                       HttpServletResponse response) {
        //生成二维码至本地，并从本地取出，送入response.output
        String fileName = QRPath + id + ".jpg";
        File file = new File(fileName);
        if (file.exists()) {

            response.setContentType("application/force-download");// 设置强制下载不打开
            response.addHeader("Content-Disposition",
                    "attachment;fileName=" + id + ".jpg");// 设置文件名

            byte[] buffer = new byte[1024];
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                OutputStream out = response.getOutputStream();
                int i = bis.read(buffer);
                while (i != -1) {
                    out.write(buffer, 0, i);
                    i = bis.read(buffer);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    //下载Excel表格模板
    @GetMapping("/excel/download")
    public void excelDownload(HttpServletResponse response) {
        //生成二维码至本地，并从本地取出，送入response.output
        String fileName = excelPath;
        File file = new File(fileName);
        if (file.exists()) {
            // 配置文件下载
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream");
            // 下载文件能正常显示中文
            response.addHeader("Content-Disposition",
                    "attachment;fileName=" + excelPath.substring(excelPath.lastIndexOf("/") + 1));// 设置文件名

            byte[] buffer = new byte[1024];
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                OutputStream out = response.getOutputStream();
                int i = bis.read(buffer);
                while (i != -1) {
                    out.write(buffer, 0, i);
                    i = bis.read(buffer);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }


    //上传Excel表格
    @ResponseBody
    @PostMapping("/excel/upload")
    public RestResult excelUpload(MultipartFile file) {
        if (file.isEmpty()) {
            return ResultUtil.fail("请选择文件");
        }
        List<User> users = ExcelUtil.readExcel(file);
        //为每一个用户设置初始密码为身份证后六位
        users.forEach(
                u -> {
                    String encodePass = SecureUtil.encryptBasedDes(u.getPassword());
                    u.setPassword(encodePass);
                    u.setRole("user");
                }
        );
        userService.saveBatch(users);
        return ResultUtil.success("导入成功");
    }

    /**
     * 上传候选人的视频和照片信息
     *
     * @param cid     候选人id
     * @param vid     投票事件id
     * @param request 获取多文件
     * @return
     */
    @ResponseBody
    @PostMapping("/media/upload")
    public RestResult revise(@RequestParam("cid") Integer cid,
                             @RequestParam("vid") Integer vid,
                             HttpServletRequest request) {

        List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
        MultipartFile file = null;
        BufferedOutputStream out = null;
        String type;
        //先查询这个候选人
        Candidate candidate = candidateService.getCandidateById(cid);

        for (int i = 0; i < files.size(); ++i) {
            file = files.get(i);
            //检测文件的类型
            if (!file.isEmpty()) {
                try {
                    type = FileUtil.detectFileType(new BufferedInputStream(file.getInputStream()));
                    byte[] bytes = file.getBytes();
                    //如果文件是jpg类型
                    if (type.equals("image/jpeg")) {
                        File newFile = new File(picPath + candidate.getUser().getJobNumber() + vid);
                        if (!newFile.exists())
                            newFile.mkdirs();

                        out = new BufferedOutputStream(new FileOutputStream(new File(picPath +
                                candidate.getUser().getJobNumber() + vid + "/pic.jpg")));
                        out.write(bytes);

                        ImgUtil.resizeImage(new File(picPath +
                                candidate.getUser().getJobNumber() + vid + "/pic.jpg"));

                        candidate.setPhotoUrl(candidate.getUser().getJobNumber() + vid);
                    } else if (type.equals("video/quicktime")) {
                        String videoUrl = "/" + candidate.getUser().getJobNumber() + vid;
                        //如果文件是mp4类型
                        File newFile = new File(videoPath + videoUrl);
                        if (!newFile.exists())
                            newFile.mkdirs();
                        out = new BufferedOutputStream(new FileOutputStream(
                                new File(videoPath + videoUrl + "/video.mp4")));

                        out.write(bytes);

                        String source = videoPath + videoUrl + "/video.mp4";
                        String target = m3u8Path  + videoUrl;

                        FileUtil.processMedia(source, target);

                        candidate.setVideoUrl(candidate.getUser().getJobNumber() + vid);
                    } else if (type.equals("application/x-tika-ooxml")) {
                        File newFile = new File(htmlPath + candidate.getUser().getJobNumber() + vid);
                        if (!newFile.exists())
                            newFile.mkdirs();

                        WordUtil.word2007ToHtml(file.getInputStream(),
                                new File(htmlPath + candidate.getUser().getJobNumber() + vid + "/detail.html"),
                                new File(wordPicPath));
                        candidate.setDetails(candidate.getUser().getJobNumber() + vid);
                        boolean b = candidateService.reviseUrlById(candidate);
                        if (!b)
                            return ResultUtil.fail("上传失败");
                        return ResultUtil.success("上传成功");
                    } else {
                        return ResultUtil.fail("上传失败");
                    }
                } catch (Exception e) {
                    return ResultUtil.fail("上传失败");
                } finally {
                    try {
                        if (out != null)
                            out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            } else {
                return ResultUtil.fail("上传的文件为空");
            }
        }

        //写完文件后要更新数据库信息
        boolean b = candidateService.reviseUrlById(candidate);
        if (!b)
            return ResultUtil.fail("上传失败");
        return ResultUtil.success("上传成功");
    }
}
